• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

hasadna / open-bus-backend / 16179892870

09 Jul 2025 08:49PM UTC coverage: 86.391%. First build
16179892870

Pull #7

github

web-flow
Merge 425635d1e into 8486e82dd
Pull Request #7: feat: Update version 2

198 of 242 branches covered (81.82%)

Branch coverage included in aggregate %.

805 of 919 new or added lines in 8 files covered. (87.6%)

805 of 919 relevant lines covered (87.6%)

5.8 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

92.96
/src/controllers/issues.controller.js
1
import axios from 'axios';
1✔
2

1✔
3
/**
1✔
4
 * Create issue handler
1✔
5
 * @param {import('fastify').FastifyRequest} request
1✔
6
 * @param {import('fastify').FastifyReply} reply
1✔
7
 */
1✔
8
export async function createIssue(request, reply) {
1✔
9
  try {
10✔
10
    const { title, contactName, contactEmail, description, environment, expectedBehavior, actualBehavior, reproducibility, attachments } =
10✔
11
      request.body;
10✔
12

10✔
13
    request.log.info('GitHub issue creation started', { title, contactEmail, reproducibility });
10✔
14

10✔
15
    // Validate required environment variables
10✔
16
    const repoName = process.env.GITHUB_REPO;
10✔
17
    const repoOwner = process.env.GITHUB_OWNER;
10✔
18
    const token = process.env.GITHUB_TOKEN;
10✔
19

10✔
20
    if (!token || !repoOwner || !repoName) {
10✔
21
      request?.log?.error?.('Missing GitHub configuration', { hasToken: Boolean(token), hasOwner: Boolean(repoOwner), hasRepo: Boolean(repoName) });
1✔
22
      return reply.status(500).send({ error: 'Configuration error', message: 'GitHub configuration is incomplete' });
1✔
23
    }
1✔
24

9✔
25
    // Create the body for the GitHub issue
9✔
26
    const body = `## Contact Information\n**Contact Name:** ${contactName}\n**Contact Email:** ${contactEmail}\n\n## Issue Details\n**Description:** \n${description}\n\n**Environment:** ${environment}\n\n**Expected Behavior:** \n${expectedBehavior}\n\n**Actual Behavior:** \n${actualBehavior}\n\n**Reproducibility:** ${reproducibility}\n\n${attachments && attachments.length > 0 ? `## Attachments\n${attachments.map((url) => `- ${url}`).join('\n')}` : ''}\n\n---\n*Issue created via API on ${new Date().toISOString()}*`;
10!
27
    const labels = ['REPORTED-BY-USER'];
10✔
28
    // Create the GitHub issue
10✔
29
    const response = await axios.post(
10✔
30
      `https://api.github.com/repos/${repoOwner}/${repoName}/issues`,
10✔
31
      { title, body, labels },
10✔
32
      {
10✔
33
        headers: {
10✔
34
          Authorization: `Bearer ${token}`,
10✔
35
          'Content-Type': 'application/json',
10✔
36
          'User-Agent': 'OpenBus-Backend/1.0',
10✔
37
        },
10✔
38
        timeout: 30000,
10✔
39
      },
10✔
40
    );
10✔
41

3✔
42
    request.log.info('GitHub issue created successfully', {
3✔
43
      issueNumber: response.data.number,
3✔
44
      issueId: response.data.id,
3✔
45
    });
3✔
46

3✔
47
    return reply.status(200).send({ success: true, data: response.data });
3✔
48
  } catch (error) {
10✔
49
    request.log.error('GitHub issue creation failed', {
6✔
50
      error: error.message,
6✔
51
      stack: error.stack,
6✔
52
      body: request.body,
6✔
53
    });
6✔
54

6✔
55
    // Handle validation errors
6✔
56
    if (error.validation) {
6!
NEW
57
      request?.log?.error?.('Validation failed', { validation: error.validation });
×
NEW
58
      return reply.status(400).send({
×
NEW
59
        error: 'Validation failed',
×
NEW
60
        details: error.validation,
×
NEW
61
      });
×
NEW
62
    }
×
63

6✔
64
    // Handle GitHub API errors
6✔
65
    if (error.response) {
6✔
66
      const { status } = error.response;
3✔
67

3✔
68
      if (status === 401) {
3✔
69
        request?.log?.error?.('GitHub authentication failed');
1✔
70
        return reply.status(401).send({
1✔
71
          error: 'Authentication failed',
1✔
72
          message: 'Invalid GitHub token or insufficient permissions',
1✔
73
        });
1✔
74
      }
1✔
75
      if (status === 404) {
3✔
76
        request?.log?.error?.('GitHub repository not found');
1✔
77
        return reply.status(500).send({
1✔
78
          error: 'Repository not found',
1✔
79
          message: 'The specified GitHub repository does not exist or is not accessible',
1✔
80
        });
1✔
81
      }
1✔
82
      if (status === 422) {
1✔
83
        request?.log?.error?.('GitHub issue validation failed');
1✔
84
        return reply.status(400).send({
1✔
85
          error: 'Invalid issue data',
1✔
86
          message: 'The issue data provided is invalid or contains errors',
1✔
87
        });
1✔
88
      }
1✔
NEW
89

×
90
      request?.log?.error?.('GitHub API error', { status, statusText: error.response.statusText });
3✔
91
      return reply.status(500).send({
3✔
92
        error: 'GitHub API error',
3✔
93
        message: `Status: ${status} - ${error.response.statusText}`,
3✔
94
      });
3✔
95
    }
3✔
96

3✔
97
    // Handle timeout errors
3✔
98
    if (error.code === 'ECONNABORTED') {
6✔
99
      request?.log?.error?.('GitHub API request timeout');
1✔
100
      return reply.status(500).send({
1✔
101
        error: 'Request timeout',
1✔
102
        message: 'The GitHub API request timed out',
1✔
103
      });
1✔
104
    }
1✔
105

2✔
106
    // Handle network errors
2✔
107
    if (error.code === 'ENOTFOUND' || error.code === 'ECONNREFUSED') {
6✔
108
      request?.log?.error?.('GitHub API network error', { code: error.code });
1✔
109
      return reply.status(500).send({
1✔
110
        error: 'Network error',
1✔
111
        message: 'Unable to connect to GitHub API',
1✔
112
      });
1✔
113
    }
1✔
114

1✔
115
    request?.log?.error?.('Unexpected error in createIssue');
6✔
116
    return reply.status(500).send({
6✔
117
      error: 'Internal server error',
6✔
118
      message: 'An unexpected error occurred while creating the issue',
6✔
119
    });
6✔
120
  }
6✔
121
}
10✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc